<template>
  <div
    style="width: 100%; height: 100%; position: relative"
    :class="{ 'video-landscape': isLandscape }"
  >
    <!-- 视频播放容器：新增@click事件+动态选中Class -->
    <div
      class="video-play"
      :id="state.pid"
      @click="handleVideoClick"
      :class="{ 'is-active': videoSelected }"
    ></div>

    <!-- 无视频流占位符：仅当无流时显示 -->
    <div
      class="no-video-placeholder"
      style="z-index: 10000"
      v-if="!state.hasVideoStream"
    >
      <el-icon class="no-video-icon"><Loading /></el-icon>
      <!-- <p>暂无视频流</p> -->
    </div>

    <!-- 底部控制栏：新增v-show控制显示+@click.stop防冒泡 -->
    <div
      class="footer"
      v-if="footerVisible"
      :class="{ 'footer-fixed': !isLandscape }"
      ref="footerRef"
    >
      <!-- 原有Footer内容不变 -->
      <div class="up-controls">
        <div class="sound-control">
          <img
            src="@/assets/images/xgjd/kqshengyin.png"
            alt="关闭声音"
            @click="handleSoundToggle"
            v-if="!isMuted"
          />
          <img
            src="@/assets/images/xgjd/gb.png"
            alt="开启声音"
            @click="handleSoundToggle"
            v-if="isMuted"
          />
        </div>
        <img
          src="@/assets/images/xgjd/jietu.png"
          alt="截图"
          @click="handleCapture"
        />
        <div class="record-control">
          <img
            src="@/assets/images/xgjd/luxiang.png"
            alt="开始录像"
            @click="handleRecordToggle"
            v-if="!isRecording"
          />
          <img
            src="@/assets/images/xgjd/jsluxiang.png"
            alt="结束录像"
            @click="handleRecordToggle"
            v-if="isRecording"
          />
        </div>
        <el-dropdown placement="top" @command="handleResolutionChange">
          <el-button size="mini" class="resolution-btn">
            {{ currentResolution }}
          </el-button>
          <template #dropdown>
            <el-dropdown-menu>
              <el-dropdown-item command="1">标清</el-dropdown-item>
              <el-dropdown-item command="0">高清</el-dropdown-item>
            </el-dropdown-menu>
          </template>
        </el-dropdown>
        <div class="canel" @click="handleBack">
          <span>详情</span>
        </div>
      </div>
      <div class="down-controls">
        <img
          src="@/assets/images/xgjd/close.png"
          alt="关闭"
          @click="handleCloseCurrentVideo"
        />
        <img
          src="@/assets/images/xgjd/screenshot.png"
          alt="横屏"
          @click="handleScreenRotation"
        />
      </div>
    </div>
  </div>
</template>

<script setup>
import { ElIcon, ElMessage } from "element-plus";
import { Plus } from "@element-plus/icons-vue";
import { useRouter } from "vue-router";
import dayjs from "dayjs";

import {
  getPointUrl,
  getPointUrlBack,
  talkToseppk,
  gettalkurl,
} from "@/api/event.js";

import { reactive, ref, watch, onMounted, onBeforeUnmount } from "vue";
const emit = defineEmits(["showql", "toggleLandscape"]);

const router = useRouter();
const props = defineProps({
  vid: String,
  Times: String,
  showtab: { type: Boolean, default: true },
  isSelected: { type: Boolean, default: false },
  isLandscape: { type: Boolean, default: false },
});
// 自身横屏状态
const isLandscape = ref(false);
const state = reactive({
  myPlugin: null,
  curIndex: 0,
  pid: "one" + Math.floor(Math.random() * 1000) + 1,
  zoom: false,
  hasVideoStream: false,
});
const isMuted = ref(false);
const isRecording = ref(false);
const isTalking = ref(false);
const currentResolution = ref("标清");
let playStatus = ref(true);

// Footer显示状态 + 视频选中状态 + 定时器存储
const footerVisible = ref(false); // Footer默认隐藏
const videoSelected = ref(false); // 视频选中状态默认未激活
let footerTimer = null; // 存储定时器，避免多次点击叠加
const footerRef = ref(null); // 定义footer的ref
// 视频点击事件逻辑
const handleVideoClick = (event) => {
  // 🔍 关键：判断点击是否发生在footer内部
  const isClickInFooter = footerRef.value && footerRef.value.contains(event.target);
  if (isClickInFooter) {
    return; // 点击footer内部，不处理
  }

  if (state.hasVideoStream) {
    footerVisible.value = true;
    videoSelected.value = true;
    if (!footerTimer) {
      footerTimer = setTimeout(() => {
        footerVisible.value = false;
        videoSelected.value = false;
        footerTimer = null;
      }, 5000);
    }
  }
};

// 横屏切换方法
const handleScreenRotation = () => {
  const newLandscapeState = !isLandscape.value;
  console.log("切换横屏状态：", newLandscapeState);
  // 关闭横屏时需要重置父组件状态
  if (!newLandscapeState) {
    emit("toggleLandscape", {
      vid: props.vid,
      isLandscape: false,
    });
    // 强制同步本地状态
    isLandscape.value = false;
    videoSelected.value = false;
    footerVisible.value = false;
  } else {
    // 开启横屏时保持选中状态
    emit("toggleLandscape", {
      vid: props.vid,
      isLandscape: true,
    });
  }

  resize();
};
// 1. 关闭当前视频流（新增方法）
const handleCloseCurrentVideo = async () => {
  // 校验插件是否初始化、是否有视频流
  if (!state.myPlugin) {
    console.warning("视频插件未初始化，无法关闭视频");
    return;
  }
  if (!state.hasVideoStream) {
    console.warning("当前无正在播放的视频流");
    return;
  }

  try {
    // 调用H5player接口：停止当前窗口视频播放（curIndex为当前窗口下标）
    await state.myPlugin.JS_Stop(state.curIndex);
    state.hasVideoStream = false; // 标记无视频流
    console.log("当前视频流已关闭");
  } catch (err) {
    console.error("关闭视频流失败：", err);
    console.error(`关闭视频流失败，错误码：${err?.iErrorCode || "未知"}`);
  }
};

// 2. 静音/关闭声音
const handleSoundToggle = async () => {
  if (!state.myPlugin) {
    console.warning("视频插件未初始化，无法控制声音");
    return;
  }
  if (!state.hasVideoStream) {
    console.warning("当前无视频流，无需控制声音");
    return;
  }

  try {
    if (!isMuted.value) {
      // 当前未静音 → 关闭声音（调用H5player关闭声音接口）
      await state.myPlugin.JS_CloseSound(state.curIndex);
      console.info("已关闭声音");
    } else {
      // 当前已静音 → 开启声音（调用H5player开启声音接口）
      await state.myPlugin.JS_OpenSound(state.curIndex);
      console.info("已开启声音");
    }
    // 更新静音状态（控制图标切换）
    isMuted.value = !isMuted.value;
  } catch (err) {
    console.error("声音控制失败：", err);
    console.error(`声音控制失败，错误码：${err?.iErrorCode || "未知"}`);
  }
};

// 3. 截图功能
const handleCapture = async () => {
  if (!state.myPlugin) {
    console.warning("视频插件未初始化，无法截图");
    return;
  }
  if (!state.hasVideoStream) {
    console.warning("视频未正常播放，无法截图（需首帧显示后操作）");
    return;
  }

  // 生成唯一截图文件名（避免重复，含时间戳）
  const fileName = `screenshot_${dayjs().format("YYYYMMDDHHmmssSSS")}`;
  const fileType = "JPEG"; // 固定为JPEG格式（开发指南要求）

  try {
    // 调用H5player截图接口（自动下载到本地）
    await state.myPlugin.JS_CapturePicture(state.curIndex, fileName, fileType);
    console.log(`截图成功，文件名为：${fileName}.${fileType.toLowerCase()}`);
  } catch (err) {
    console.error("截图失败：", err);
    // 特殊处理：首帧未显示（错误码0x12f930011）
    if (err?.iErrorCode === 0x12f930011) {
      console.error("截图失败：视频首帧未显示，请稍后重试");
    } else {
      console.error(`截图失败，错误码：${err?.iErrorCode || "未知"}`);
    }
  }
};

// 4. 录像/结束录像
const handleRecordToggle = async () => {
  if (!state.myPlugin) {
    console.warning("视频插件未初始化，无法录像");
    return;
  }
  if (!state.hasVideoStream) {
    console.warning("视频未正常播放，无法录像");
    return;
  }

  // 生成唯一录像文件名（含时间戳，开发指南建议全局唯一）
  const recordFileName = `record_${dayjs().format("YYYYMMDDHHmmssSSS")}`;
  const idstType = 5; // 录像格式：5=MP4（支持AAC/G711A/G711U音频），2=PS（通用格式）

  try {
    if (!isRecording.value) {
      // 未录像 → 开始录像（调用H5player开始录像接口）
      await state.myPlugin.JS_StartSaveEx(
        state.curIndex,
        recordFileName,
        idstType
      );
      isRecording.value = true; // 更新录像状态（控制图标切换）
      console.log(`录像已开始，文件名为：${recordFileName}.mp4`);
    } else {
      // 已录像 → 结束录像（调用H5player停止录像接口）
      await state.myPlugin.JS_StopSave(state.curIndex);
      isRecording.value = false;
      console.log(`录像已结束，文件已保存`);
    }
  } catch (err) {
    console.error("录像控制失败：", err);
    // 特殊错误处理：重复开始录像（0x12f920015）、未开始录像却停止（0x12f920016）
    if (err?.iErrorCode === 0x12f920015) {
      console.error("录像失败：已在录像中，无需重复开始");
    } else if (err?.iErrorCode === 0x12f920016) {
      console.error("停止录像失败：未开启录像");
    } else {
      console.error(`录像控制失败，错误码：${err?.iErrorCode || "未知"}`);
    }
  }
};

// 5. 切换标清/高清（完善已有handleResolutionChange方法，确保传值取流正确）
const handleResolutionChange = async (command) => {
  if (!state.myPlugin) {
    console.warning("视频插件未初始化，无法切换清晰度");
    return;
  }
  if (!state.hasVideoStream) {
    console.warning("视频未播放，无需切换清晰度");
    return;
  }

  // 清晰度映射：command=1→标清（streamType=1），command=0→高清（streamType=0）
  const resolutionMap = { 1: "标清", 0: "高清" };
  const targetResolution = resolutionMap[command];

  // 若当前清晰度与目标一致，无需操作
  if (currentResolution.value === targetResolution) {
    console.info(`当前已为${targetResolution}，无需切换`);
    return;
  }

  try {
    // 1. 停止当前所有播放（避免流冲突，开发指南建议切换前停止）
    await state.myPlugin.JS_StopRealPlayAll();
    // 2. 更新当前清晰度状态
    currentResolution.value = targetResolution;
    // 3. 重新取流播放（传目标清晰度的streamType，在play方法中已处理）
    await play();
    console.log(`已切换至${targetResolution}`);
  } catch (err) {
    console.error("清晰度切换失败：", err);
    console.error(`清晰度切换失败，错误码：${err?.iErrorCode || "未知"}`);
    // 切换失败时回滚清晰度显示
    currentResolution.value = resolutionMap[command === 1 ? 0 : 1];
  }
};

const changeVideo = () => {
  playStatus.value = !playStatus.value;
  state.hasVideoStream = false;
  playStatus.value ? play() : playBack();
};
const handleBack = () => {
  const currentVideoId = props.vid;
  console.log("当前点击的视频ID：", currentVideoId);
  if (currentVideoId && currentVideoId.trim() !== "") {
    try {
      router.push({
        name: "webviewVideo", // 目标页面的路由名称（需确保路由表中已定义该名称）
        query: {
          indexCode: currentVideoId, // 传递当前视频ID给目标页面
        },
      });
    } catch (err) {
      // 异常处理：跳转失败时提示
      ElMessage.error("页面跳转失败，请稍后重试");
      console.error("跳转异常：", err);
    }
  } else {
    // ID无效：显示错误提示，不跳转
    ElMessage.warning("未获取到有效的视频ID，无法进入详情页");
    console.warning("当前视频ID为空或无效：", currentVideoId);
  }
};
const playBack = async () => {
  state.hasVideoStream = false;
  try {
    const bt = dayjs(new Date(props.Times))
      .subtract(10, "second")
      .format("YYYY-MM-DDTHH:mm:ss.SSSZ");
    const et = dayjs(new Date(props.Times))
      .add(10, "second")
      .format("YYYY-MM-DDTHH:mm:ss.SSSZ");
    const pm = { cameraId: props.vid, beginTime: bt, endTime: et, uuid: "" };
    const { data } = await getPointUrlBack({ ...pm });
    if (data?.url) {
      await state.myPlugin
        .JS_Play(data.url, { playURL: data.url, mode: 1 }, 0, bt, et)
        .then(
          () => {
            state.hasVideoStream = true;
            resize();
          },
          (err) => {
            state.hasVideoStream = false;
            console.error("回放播放失败：", err);
            console.error("回放视频播放失败");
          }
        );
    } else {
      state.hasVideoStream = false;
      console.warning("未获取到回放视频流地址");
    }
  } catch (e) {
    state.hasVideoStream = false;
    console.error("获取回放流异常：", e);
    console.error("获取回放视频流失败");
  }
};
const play = async () => {
  state.hasVideoStream = false;
  const ids = [props.vid];
  try {
    const { data } = await getPointUrl({
      deviceIds: ids,
      ifwww: "1",
      streamType: currentResolution.value === "标清" ? "1" : "0",
    });
    const urls = data.cameraUrls || [];
    if (urls.length > 0) {
      state.myPlugin.JS_StopRealPlayAll();
      for (let i = 0; i < urls.length; i++) {
        if (i > 8) break;
        await state.myPlugin
          .JS_Play(
            urls[i].cameraUrl,
            { playURL: urls[i].cameraUrl, mode: 1 },
            i
          )
          .then(
            () => {
              state.hasVideoStream = true;
              resize();
            },
            (err) => {
              state.hasVideoStream = false;
              console.error("实时播放失败：", err);
              console.error("实时视频播放失败");
            }
          );
      }
    } else {
      state.hasVideoStream = false;
      console.warning("未获取到实时视频流地址");
    }
  } catch (e) {
    state.hasVideoStream = false;
    console.error("获取实时流异常：", e);
    console.error("获取实时视频流失败");
  }
};
const initPlayer = () => {
  if (state.myPlugin) return;
  state.myPlugin = new JSPlugin({
    szId: state.pid,
    szBasePath: "/js/",
    bSupporDoubleClickFull: false,
    iMaxSplit: 1,
    iCurrentSplit: 1,
  });
  state.myPlugin.JS_SetWindowControlCallback({
    windowEventSelect: (index) => {
      state.curIndex = index;
    },
    pluginErrorHandler: (iWndIndex, iErrorCode, oError) => {
      console.error(`窗口-${iWndIndex} 播放错误，码：${iErrorCode}`, oError);
      state.hasVideoStream = false;
      console.error(`视频播放失败，错误码：${iErrorCode}`);
      play();
    },
    windowFullCcreenChange: (bFull) => {
      setTimeout(() => {
        state.myPlugin.JS_Resize();
      }, 50);
    },
  });
};
const destoryPlayer = () => {
  if (state.myPlugin) {
    state.myPlugin.JS_StopRealPlayAll();
    state.myPlugin.JS_DestroyWorker();
    state.myPlugin = null;
    state.hasVideoStream = false;
  }
};
const resize = () => {
  console.log("视频容器大小适配");
  if (state.myPlugin) {
    setTimeout(() => {
      state.myPlugin.JS_Resize();
    }, 50);
  }
};
const zoom = () => {
  state.zoom = !state.zoom;
  if (state.zoom) {
    state.myPlugin.JS_EnableZoom(state.curIndex).then(
      () => {
        console.info("视频缩放功能已开启");
      },
      (err) => {
        console.error("开启视频缩放失败：", err);
        state.zoom = false;
      }
    );
  } else {
    console.info("视频缩放功能已关闭");
  }
};
const startTalk = async (szTalkUrl) => {
  console.log("开始对讲，地址：", szTalkUrl);
  try {
    if (!szTalkUrl) {
      console.log("未获取到对讲地址");
      console.warning("未获取到对讲地址");
      return;
    }
    state.myPlugin.JS_StartTalk(szTalkUrl).then(
      () => {
        console.info("对讲启动成功");
        console.log("对讲已开始");
      },
      (err) => {
        console.error("对讲启动失败：", err);
        console.error("对讲启动失败");
      }
    );
  } catch (e) {
    console.error("对讲异常：", e);
    console.error("对讲过程中出现异常");
  }
};
const stopTalk = () => {
  if (state.myPlugin) {
    state.myPlugin.JS_StopTalk().then(
      () => {
        console.info("对讲停止成功");
        console.log("对讲已结束");
      },
      (err) => {
        console.error("对讲停止失败：", err);
        console.error("对讲停止失败");
      }
    );
  } else {
    console.warning("视频插件未初始化，无法停止对讲");
  }
};

watch(
  () => props.isLandscape,
  (newVal) => {
    console.log("子组件同步父组件横屏状态：", newVal);
    isLandscape.value = newVal; // 同步横屏状态

    // ③ 关键：关闭横屏时，彻底重置子组件样式相关状态
    if (!newVal) {
      videoSelected.value = false; // 取消视频选中（避免残留边框）
      footerVisible.value = false; // 隐藏控制栏（恢复多画面默认）
      if (footerTimer) clearTimeout(footerTimer); // 清除控制栏定时器
    } else {
      // 打开横屏时，保持选中和控制栏显示（原有逻辑）
      videoSelected.value = true;
      footerVisible.value = true;
    }

    // ④ 同步状态后，触发子组件resize（适配多画面/横屏尺寸）
    resize();
  },
  { immediate: true } // 初始化时就同步父组件状态（避免初始样式错乱）
);
watch(
  () => props.vid,
  (newVal) => {
    if (newVal && newVal.trim() !== "") {
      state.hasVideoStream = false;
      play();
    }
  },
  { immediate: true, deep: true }
);
watch(() => state.hasVideoStream, (newVal) => {
  if (!newVal) {
    footerVisible.value = false;
    videoSelected.value = false;
    if (footerTimer) {
      clearTimeout(footerTimer);
      footerTimer = null;
    }
  }
});
// 7. 新增：组件卸载时清除定时器（避免内存泄漏）
onMounted(() => {
  initPlayer();
});
onBeforeUnmount(() => {
  destoryPlayer();
  if (footerTimer) {
    clearTimeout(footerTimer);
    footerTimer = null; // 清空变量，避免残留引用
    console.log("组件卸载，清除定时器");
  }
});

// 原有暴露方法不变
defineExpose({ resize, startTalk, stopTalk, changeVideo, zoom });
</script>

<style lang="scss" scoped>
// 原有样式不变，新增视频选中效果样式
.video-play {
  width: 100% !important;
  height: 100% !important;
  // 原有背景（可选：默认黑色更符合视频场景）
  background: #000;
}

//
.video-play.is-active {
  border: 2px solid #409eff;
  box-shadow: 0 0 15px rgba(64, 158, 255, 0.8); // 发光阴影，增强视觉突出
}
.no-video-placeholder {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  background: #5f5f5f !important;
  z-index: 5;
  pointer-events: none;
  border: 1px solid rgb(255, 204, 0);
  p {
    color: #ffffff;
    font-size: 16px;
    margin-top: 12px;
  }

  ::v-deep .no-video-icon {
    font-size: 30px;
    color: #ffffff;
    font-weight: bold;
    // animation: rotate 2s linear infinite;
  }
}

.footer {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  height: 80px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-around;
  background: #1c1b1b;
  color: white;
  z-index: 100;
  padding: 0 20px;
  opacity: 1;

  .up-controls {
    width: 100%;
    z-index: 100;
    background: #1c1b1b;
    display: flex;
    justify-content: space-around;
    align-items: center;

    .sound-control,
    .record-control,
    .canel {
      display: flex;
    }
    .canel span {
      color: #ffffff;
    }
    img {
      width: 30px;
      height: 30px;
    }
    .clear {
      background: #ffffff;
      span {
        display: flex;
        align-items: center;
        font-size: 12px;
        padding: 2px 5px;
      }
    }
  }
  .down-controls {
    width: 100%;
    display: flex;
    justify-content: space-between;
    img {
      width: 30px;
      height: 30px;
    }
  }
}

// 原有动画样式不变
@keyframes rotate {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

.video-landscape {
  position: fixed !important;
  top: 0 !important;
  left: 0 !important;
  right: 0 !important;
  bottom: 0 !important;
  z-index: 9999 !important; // 最高层级，确保覆盖其他视频
  background-color: #000 !important; // 背景涂黑，避免透底
  overflow: hidden;
}

.footer {
  position: absolute; // 横屏时：相对于视频容器定位
  bottom: 0;
  left: 0;
  right: 0;
  height:  80px;
  background: #1c1b1b;
  color: white;
  z-index: 99999999 !important; // 高于视频，确保可见
  padding: 0 20px;

  // 非横屏时恢复固定定位
  &.footer-fixed {
    position: fixed;
  }
}

// 4. 无视频流占位符：横屏时居中
.no-video-placeholder {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  background: #5f5f5f;
  z-index: 5;
  pointer-events: none;

  p {
    color: #fff;
    font-size: 16px;
    margin-top: 12px;
  }

  ::v-deep .no-video-icon {
    font-size: 30px;
    color: #fff;
    font-weight: bold;
    // animation: rotate 2s linear infinite;
  }
}
</style>
